Code Coverage |
||||||||||||||||
Lines |
Branches |
Paths |
Functions and Methods |
Classes and Traits |
||||||||||||
| Total | |
46.86% |
97 / 207 |
|
40.88% |
74 / 181 |
|
4.51% |
12 / 266 |
|
8.33% |
2 / 24 |
CRAP | |
0.00% |
0 / 1 |
| DAO | |
46.86% |
97 / 207 |
|
40.88% |
74 / 181 |
|
4.51% |
12 / 266 |
|
8.33% |
2 / 24 |
10263.56 | |
0.00% |
0 / 1 |
| __construct | |
75.00% |
3 / 4 |
|
75.00% |
3 / 4 |
|
33.33% |
1 / 3 |
|
0.00% |
0 / 1 |
5.67 | |||
| retrieve | |
83.33% |
5 / 6 |
|
75.00% |
3 / 4 |
|
33.33% |
1 / 3 |
|
0.00% |
0 / 1 |
5.67 | |||
| retrieveRange | |
0.00% |
0 / 13 |
|
0.00% |
0 / 13 |
|
0.00% |
0 / 25 |
|
0.00% |
0 / 1 |
56 | |||
| countRecords | |
0.00% |
0 / 4 |
|
0.00% |
0 / 3 |
|
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| concat | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| update | |
83.33% |
5 / 6 |
|
75.00% |
3 / 4 |
|
33.33% |
1 / 3 |
|
0.00% |
0 / 1 |
5.67 | |||
| replace | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getInsertId | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| _getInsertId | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| datetimeToDB | |
0.00% |
0 / 5 |
|
0.00% |
0 / 5 |
|
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
12 | |||
| dateToDB | |
0.00% |
0 / 5 |
|
0.00% |
0 / 5 |
|
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
12 | |||
| datetimeFromDB | |
0.00% |
0 / 1 |
|
0.00% |
0 / 4 |
|
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| dateFromDB | |
0.00% |
0 / 1 |
|
0.00% |
0 / 4 |
|
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| convertFromDB | |
84.21% |
16 / 19 |
|
77.27% |
17 / 22 |
|
16.67% |
4 / 24 |
|
0.00% |
0 / 1 |
127.43 | |||
| getType | |
33.33% |
4 / 12 |
|
25.00% |
3 / 12 |
|
10.00% |
1 / 10 |
|
0.00% |
0 / 1 |
99.21 | |||
| convertToDB | |
50.00% |
14 / 28 |
|
46.88% |
15 / 32 |
|
1.28% |
1 / 78 |
|
0.00% |
0 / 1 |
366.29 | |||
| nullOrInt | |
0.00% |
0 / 1 |
|
0.00% |
0 / 4 |
|
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| getAdditionalFieldNames | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getLocaleFieldNames | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| updateDataObjectSettings | |
68.75% |
33 / 48 |
|
64.52% |
20 / 31 |
|
0.00% |
0 / 80 |
|
0.00% |
0 / 1 |
16.39 | |||
| getDataObjectSettings | |
86.67% |
13 / 15 |
|
80.00% |
8 / 10 |
|
12.50% |
1 / 8 |
|
0.00% |
0 / 1 |
14.72 | |||
| getDirectionMapping | |
0.00% |
0 / 5 |
|
0.00% |
0 / 5 |
|
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
20 | |||
| getDataChangedEvent | |
0.00% |
0 / 8 |
|
0.00% |
0 / 4 |
|
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
12 | |||
| formatDateToDB | |
0.00% |
0 / 12 |
|
0.00% |
0 / 9 |
|
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
30 | |||
| 1 | <?php |
| 2 | |
| 3 | /** |
| 4 | * @defgroup db DB |
| 5 | * Implements basic database concerns such as connection abstraction. |
| 6 | */ |
| 7 | |
| 8 | /** |
| 9 | * @file classes/db/DAO.php |
| 10 | * |
| 11 | * Copyright (c) 2014-2021 Simon Fraser University |
| 12 | * Copyright (c) 2000-2021 John Willinsky |
| 13 | * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING. |
| 14 | * |
| 15 | * @class DAO |
| 16 | * |
| 17 | * @ingroup db |
| 18 | * |
| 19 | * @see DAORegistry |
| 20 | * |
| 21 | * @brief Operations for retrieving and modifying objects from a database. |
| 22 | */ |
| 23 | |
| 24 | namespace PKP\db; |
| 25 | |
| 26 | use Generator; |
| 27 | use Illuminate\Database\Query\Builder; |
| 28 | use Illuminate\Support\Facades\DB; |
| 29 | use PKP\core\DataObject; |
| 30 | use PKP\core\JSONMessage; |
| 31 | use PKP\plugins\Hook; |
| 32 | |
| 33 | class DAO |
| 34 | { |
| 35 | public const SORT_DIRECTION_ASC = 1; |
| 36 | public const SORT_DIRECTION_DESC = 2; |
| 37 | |
| 38 | /** |
| 39 | * Constructor. |
| 40 | * Initialize the database connection. |
| 41 | */ |
| 42 | public function __construct($callHooks = true) |
| 43 | { |
| 44 | if ($callHooks === true) { |
| 45 | // Call hooks based on the object name. Results |
| 46 | // in hook calls named e.g. "DAO_CLASS::_Constructor" |
| 47 | $classNameParts = explode('\\', get_class($this)); // Separate namespace info from class name |
| 48 | if (Hook::run(strtolower(end($classNameParts)) . '::_Constructor', [$this])) { |
| 49 | return; |
| 50 | } |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | /** |
| 55 | * Execute a SELECT SQL statement. |
| 56 | * |
| 57 | * @param string $sql the SQL statement |
| 58 | * @param array $params parameters for the SQL statement |
| 59 | * |
| 60 | * @deprecated 3.4 |
| 61 | * |
| 62 | * @return Generator<int,object> |
| 63 | */ |
| 64 | public function retrieve(string $sql, array $params = [], bool $callHooks = true): Generator |
| 65 | { |
| 66 | if ($callHooks === true) { |
| 67 | $trace = debug_backtrace(); |
| 68 | // Call hooks based on the calling entity, assuming |
| 69 | // this method is only called by a subclass. Results |
| 70 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 71 | // (always lower case). |
| 72 | $value = null; |
| 73 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$value])) { |
| 74 | return $value; |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | return DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 79 | } |
| 80 | |
| 81 | /** |
| 82 | * Execute a SELECT SQL statement, returning rows in the range supplied. |
| 83 | * |
| 84 | * @param $sql the SQL statement |
| 85 | * @param $params parameters for the SQL statement, params is used only when $sql is a string |
| 86 | * @param $dbResultRange object describing the desired range |
| 87 | * |
| 88 | * @deprecated 3.4 |
| 89 | */ |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 93 | $trace = debug_backtrace(); |
| 94 | // Call hooks based on the calling entity, assuming |
| 95 | // this method is only called by a subclass. Results |
| 96 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 97 | $value = null; |
| 98 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$dbResultRange, &$value])) { |
| 99 | return $value; |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 108 | $sql->limit($limit)->offset($offset); |
| 109 | } else { |
| 110 | $sql .= " LIMIT {$limit} OFFSET {$offset}"; |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 116 | |
| 117 | /** |
| 118 | * Count the number of records in the supplied SQL statement (with optional bind parameters parameters) |
| 119 | * |
| 120 | * @param $sql SQL query to be counted |
| 121 | * @param $params Optional SQL query bind parameters, only used when the $sql argument is a string |
| 122 | * |
| 123 | * @deprecated 3.4 |
| 124 | */ |
| 125 | public function countRecords(string|Builder $sql, array $params = []): int |
| 126 | { |
| 127 | // In case a Laravel Builder has been received, drop its SELECT and ORDER BY clauses for optimization purposes |
| 128 | if ($sql instanceof Builder) { |
| 129 | return $sql->getCountForPagination(); |
| 130 | } |
| 131 | $result = $this->retrieve('SELECT COUNT(*) AS row_count FROM (' . $sql . ') AS count_subquery', $params); |
| 132 | return $result->current()->row_count; |
| 133 | } |
| 134 | |
| 135 | /** |
| 136 | * Concatenate SQL expressions into a single string. |
| 137 | * |
| 138 | * @param array ...$args SQL expressions (e.g. column names) to concatenate. |
| 139 | * |
| 140 | * @deprecated 3.4 |
| 141 | */ |
| 142 | public function concat(...$args): string |
| 143 | { |
| 144 | return 'CONCAT(' . join(',', $args) . ')'; |
| 145 | } |
| 146 | |
| 147 | /** |
| 148 | * Execute an INSERT, UPDATE, or DELETE SQL statement. |
| 149 | * |
| 150 | * @param $sql the SQL statement the execute |
| 151 | * @param $params an array of parameters for the SQL statement |
| 152 | * @param $callHooks Whether or not to call hooks |
| 153 | * @param $dieOnError Whether or not to die if an error occurs |
| 154 | * |
| 155 | * @deprecated 3.4 |
| 156 | * |
| 157 | * @return Affected row count |
| 158 | */ |
| 159 | public function update(string $sql, array $params = [], bool $callHooks = true, bool $dieOnError = true): int |
| 160 | { |
| 161 | if ($callHooks === true) { |
| 162 | $trace = debug_backtrace(); |
| 163 | // Call hooks based on the calling entity, assuming |
| 164 | // this method is only called by a subclass. Results |
| 165 | // in hook calls named e.g. "DAO_CLASS::_updateobject" |
| 166 | // (all lowercase) |
| 167 | $value = null; |
| 168 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$value])) { |
| 169 | return $value; |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | return DB::affectingStatement($sql, $params); |
| 174 | } |
| 175 | |
| 176 | /** |
| 177 | * Insert a row in a table, replacing an existing row if necessary. |
| 178 | * |
| 179 | * @param $arrFields Associative array of colName => value |
| 180 | * @param $keyCols Array of column names that are keys |
| 181 | * |
| 182 | * @deprecated 3.4 |
| 183 | */ |
| 184 | public function replace(string $table, array $arrFields, array $keyCols): void |
| 185 | { |
| 186 | $matchValues = array_filter($arrFields, fn ($key) => in_array($key, $keyCols), ARRAY_FILTER_USE_KEY); |
| 187 | $additionalValues = array_filter($arrFields, fn ($key) => !in_array($key, $keyCols), ARRAY_FILTER_USE_KEY); |
| 188 | DB::table($table)->updateOrInsert($matchValues, $additionalValues); |
| 189 | } |
| 190 | |
| 191 | /** |
| 192 | * Return the last ID inserted in an autonumbered field. |
| 193 | */ |
| 194 | protected function getInsertId(): int |
| 195 | { |
| 196 | return DB::getPdo()->lastInsertId(); |
| 197 | } |
| 198 | |
| 199 | /** |
| 200 | * Return the last ID inserted in an autonumbered field. |
| 201 | * |
| 202 | * @deprecated 3.4 |
| 203 | */ |
| 204 | public function _getInsertId(): int |
| 205 | { |
| 206 | return $this->getInsertId(); |
| 207 | } |
| 208 | |
| 209 | /** |
| 210 | * Return datetime formatted for DB insertion. |
| 211 | * |
| 212 | * @param $dt *nix timestamp or ISO datetime string |
| 213 | * |
| 214 | * @deprecated 3.4 |
| 215 | */ |
| 216 | public function datetimeToDB(null|int|string $dt): string |
| 217 | { |
| 218 | if ($dt === null) { |
| 219 | return 'NULL'; |
| 220 | } |
| 221 | if (!ctype_digit((string) $dt)) { |
| 222 | $dt = strtotime($dt); |
| 223 | } |
| 224 | return '\'' . date('Y-m-d H:i:s', $dt) . '\''; |
| 225 | } |
| 226 | |
| 227 | /** |
| 228 | * Return date formatted for DB insertion. |
| 229 | * |
| 230 | * @param $d *nix timestamp or ISO date string |
| 231 | * |
| 232 | * @deprecated 3.4 |
| 233 | */ |
| 234 | public function dateToDB(null|int|string $d): string |
| 235 | { |
| 236 | if ($d === null) { |
| 237 | return 'NULL'; |
| 238 | } |
| 239 | if (!ctype_digit($d)) { |
| 240 | $d = strtotime($d); |
| 241 | } |
| 242 | return '\'' . date('Y-m-d', $d) . '\''; |
| 243 | } |
| 244 | |
| 245 | /** |
| 246 | * Return datetime from DB as ISO datetime string. |
| 247 | * |
| 248 | * @deprecated 3.4 |
| 249 | */ |
| 250 | public function datetimeFromDB(?string $dt): ?string |
| 251 | { |
| 252 | return $dt === null ? null : date('Y-m-d H:i:s', strtotime($dt)); |
| 253 | } |
| 254 | |
| 255 | /** |
| 256 | * Return date from DB as ISO date string. |
| 257 | * |
| 258 | * @deprecated 3.4 |
| 259 | */ |
| 260 | public function dateFromDB(?string $d): ?string |
| 261 | { |
| 262 | return $d === null ? null : date('Y-m-d', strtotime($d)); |
| 263 | } |
| 264 | |
| 265 | /** |
| 266 | * Convert a value from the database to a specific type |
| 267 | * |
| 268 | * @param $value Value from the database |
| 269 | * @param $type Type from the database, eg `string` |
| 270 | * @param $nullable True iff the value is allowed to be null |
| 271 | */ |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 275 | return null; |
| 276 | } |
| 277 | switch ($type) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 280 | return (bool) $value; |
| 281 | case 'int': |
| 282 | case 'integer': |
| 283 | return (int) $value; |
| 284 | case 'float': |
| 285 | case 'number': |
| 286 | return (float) $value; |
| 287 | case 'object': |
| 288 | case 'array': |
| 289 | return json_decode($value, true); |
| 290 | case 'date': |
| 291 | return strtotime($value); |
| 292 | case 'string': |
| 293 | default: |
| 294 | // Nothing required. |
| 295 | break; |
| 296 | } |
| 297 | return $value; |
| 298 | } |
| 299 | |
| 300 | /** |
| 301 | * Get the type of a value to be stored in the database |
| 302 | * |
| 303 | * @deprecated 3.4 |
| 304 | */ |
| 305 | public function getType(mixed $value): string |
| 306 | { |
| 307 | return match(gettype($value)) { |
| 308 | 'boolean' => 'bool', |
| 309 | 'bool' => 'bool', |
| 310 | 'integer' => 'int', |
| 311 | 'int' => 'int', |
| 312 | 'double' => 'float', |
| 313 | 'float' => 'float', |
| 314 | 'array' => 'object', |
| 315 | 'object' => 'object', |
| 316 | 'string' => 'string', |
| 317 | default => 'string' |
| 318 | }; |
| 319 | } |
| 320 | |
| 321 | /** |
| 322 | * Convert a PHP variable into a string to be stored in the DB |
| 323 | * |
| 324 | * @param bool $nullable True iff the value is allowed to be null. |
| 325 | * |
| 326 | * @return string |
| 327 | */ |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 331 | return null; |
| 332 | } |
| 333 | |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 341 | $value = json_encode($value, JSON_UNESCAPED_UNICODE); |
| 342 | break; |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 345 | // Cast to boolean, ensuring that string |
| 346 | // "false" evaluates to boolean false |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 349 | case 'int': |
| 350 | case 'integer': |
| 351 | $value = (int) $value; |
| 352 | break; |
| 353 | case 'float': |
| 354 | case 'number': |
| 355 | $value = (float) $value; |
| 356 | break; |
| 357 | case 'date': |
| 358 | if ($value !== null) { |
| 359 | if (!is_numeric($value)) { |
| 360 | $value = strtotime($value); |
| 361 | } |
| 362 | $value = date('Y-m-d H:i:s', $value); |
| 363 | } |
| 364 | break; |
| 365 | case 'string': |
| 366 | default: |
| 367 | // do nothing. |
| 368 | } |
| 369 | |
| 370 | return $value; |
| 371 | } |
| 372 | |
| 373 | /** |
| 374 | * Cast the given parameter to an int, or leave it null. |
| 375 | * |
| 376 | * @deprecated 3.4 |
| 377 | */ |
| 378 | public function nullOrInt(mixed $value): ?int |
| 379 | { |
| 380 | return (empty($value) ? null : (int) $value); |
| 381 | } |
| 382 | |
| 383 | /** |
| 384 | * Get a list of additional field names to store in this DAO. |
| 385 | * This can be used to extend the table with virtual "columns", |
| 386 | * typically using the ..._settings table. |
| 387 | * |
| 388 | * @deprecated 3.4 |
| 389 | * |
| 390 | * @return array List of strings representing field names. |
| 391 | */ |
| 392 | public function getAdditionalFieldNames(): array |
| 393 | { |
| 394 | $returner = []; |
| 395 | // Call hooks based on the calling entity, assuming |
| 396 | // this method is only called by a subclass. Results |
| 397 | // in hook calls named e.g. "DAO_CLASS::getAdditionalFieldNames" |
| 398 | // (class names lowercase) |
| 399 | $classNameParts = explode('\\', get_class($this)); // Separate namespace info from class name |
| 400 | Hook::run(strtolower(end($classNameParts)) . '::getAdditionalFieldNames', [$this, &$returner]); |
| 401 | |
| 402 | return $returner; |
| 403 | } |
| 404 | |
| 405 | /** |
| 406 | * Get locale field names. Like getAdditionalFieldNames, but for |
| 407 | * localized (multilingual) fields. |
| 408 | * |
| 409 | * @see getAdditionalFieldNames |
| 410 | * @deprecated 3.4 |
| 411 | * |
| 412 | * @return array Array of string field names. |
| 413 | */ |
| 414 | public function getLocaleFieldNames(): array |
| 415 | { |
| 416 | $returner = []; |
| 417 | // Call hooks based on the calling entity, assuming |
| 418 | // this method is only called by a subclass. Results |
| 419 | // in hook calls named e.g. "DAO_CLASS::getLocaleFieldNames" |
| 420 | // (class names lowercase) |
| 421 | $classNameParts = explode('\\', get_class($this)); // Separate namespace info from class name |
| 422 | Hook::run(strtolower(end($classNameParts)) . '::getLocaleFieldNames', [$this, &$returner]); |
| 423 | |
| 424 | return $returner; |
| 425 | } |
| 426 | |
| 427 | /** |
| 428 | * Update the settings table of a data object. |
| 429 | * |
| 430 | * @deprecated 3.4 |
| 431 | */ |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 521 | |
| 522 | /** |
| 523 | * Get contents of the _settings table, storing entries in the specified |
| 524 | * data object. |
| 525 | * |
| 526 | * @param $tableName Settings table name |
| 527 | * @param $idFieldName Name of ID column |
| 528 | * @param $dataObject Object in which to store retrieved values |
| 529 | * |
| 530 | * @deprecated 3.4 |
| 531 | */ |
| 532 | public function getDataObjectSettings(string $tableName, string $idFieldName, int $idFieldValue, DataObject $dataObject) |
| 533 | { |
| 534 | if ($idFieldName !== null) { |
| 535 | $sql = "SELECT * FROM {$tableName} WHERE {$idFieldName} = ?"; |
| 536 | $params = [$idFieldValue]; |
| 537 | } else { |
| 538 | $sql = "SELECT * FROM {$tableName}"; |
| 539 | $params = []; |
| 540 | } |
| 541 | $result = $this->retrieve($sql, $params); |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 550 | ); |
| 551 | } |
| 552 | } |
| 553 | |
| 554 | /** |
| 555 | * Get the direction specifier for sorting from a SORT_DIRECTION_... constant. |
| 556 | * |
| 557 | * @deprecated 3.4 |
| 558 | */ |
| 559 | public function getDirectionMapping(int $direction): string |
| 560 | { |
| 561 | return match($direction) { |
| 562 | self::SORT_DIRECTION_ASC => 'ASC', |
| 563 | self::SORT_DIRECTION_DESC => 'DESC', |
| 564 | default => 'ASC' |
| 565 | }; |
| 566 | } |
| 567 | |
| 568 | /** |
| 569 | * Generate a JSON message with an event that can be sent |
| 570 | * to the client to refresh itself according to changes |
| 571 | * in the DB. |
| 572 | * |
| 573 | * @param $elementId (Optional) To refresh a single element |
| 574 | * give the element ID here. Otherwise all elements will |
| 575 | * be refreshed. |
| 576 | * @param $parentElementId (Optional) To refresh a single |
| 577 | * element that is associated with another one give the parent |
| 578 | * element ID here. |
| 579 | * @param $content (Optional) Additional content to pass back |
| 580 | * to the handler of the JSON message. |
| 581 | * |
| 582 | * @deprecated 3.4 |
| 583 | */ |
| 584 | public static function getDataChangedEvent(?string $elementId = null, ?string $parentElementId = null, string $content = ''): JSONMessage |
| 585 | { |
| 586 | // Create the event data. |
| 587 | $eventData = null; |
| 588 | if ($elementId) { |
| 589 | $eventData = [$elementId]; |
| 590 | if (strlen($parentElementId ?? '') > 0) { |
| 591 | $eventData['parentElementId'] = $parentElementId; |
| 592 | } |
| 593 | } |
| 594 | |
| 595 | // Create and render the JSON message with the |
| 596 | // event to be triggered on the client side. |
| 597 | $json = new JSONMessage(true, $content); |
| 598 | $json->setEvent('dataChanged', $eventData); |
| 599 | return $json; |
| 600 | } |
| 601 | |
| 602 | /** |
| 603 | * Format a passed date (in English textual datetime) |
| 604 | * to Y-m-d H:i:s format, used in database. |
| 605 | * |
| 606 | * @param string $date Any English textual datetime. |
| 607 | * @param int $defaultNumWeeks If passed and date is null, |
| 608 | * used to calculate a data in future from today. |
| 609 | * @param bool $acceptPastDate Will not accept past dates, |
| 610 | * returning today if false and the passed date |
| 611 | * is in the past. |
| 612 | * |
| 613 | * @deprecated 3.4 |
| 614 | */ |
| 615 | protected function formatDateToDB(string $date, ?int $defaultNumWeeks = null, bool $acceptPastDate = true): ?string |
| 616 | { |
| 617 | $today = getDate(); |
| 618 | $todayTimestamp = mktime(0, 0, 0, $today['mon'], $today['mday'], $today['year']); |
| 619 | if ($date != null) { |
| 620 | $dateParts = explode('-', $date); |
| 621 | |
| 622 | // If we don't accept past dates... |
| 623 | if (!$acceptPastDate && $todayTimestamp > strtotime($date)) { |
| 624 | // ... return today. |
| 625 | return date('Y-m-d H:i:s', $todayTimestamp); |
| 626 | } else { |
| 627 | // Return the passed date. |
| 628 | return date('Y-m-d H:i:s', mktime(0, 0, 0, $dateParts[1], $dateParts[2], $dateParts[0])); |
| 629 | } |
| 630 | } elseif (isset($defaultNumWeeks)) { |
| 631 | // Add the equivalent of $numWeeks weeks, measured in seconds, to $todaysTimestamp. |
| 632 | $numWeeks = max((int) $defaultNumWeeks, 2); |
| 633 | $newDueDateTimestamp = $todayTimestamp + ($numWeeks * 7 * 24 * 60 * 60); |
| 634 | return date('Y-m-d H:i:s', $newDueDateTimestamp); |
| 635 | } else { |
| 636 | // Either the date or the defaultNumWeeks must be set |
| 637 | assert(false); |
| 638 | return null; |
| 639 | } |
| 640 | } |
| 641 | } |
| 642 | |
| 643 | if (!PKP_STRICT_MODE) { |
| 644 | class_alias('\PKP\db\DAO', '\DAO'); |
| 645 | define('SORT_DIRECTION_ASC', DAO::SORT_DIRECTION_ASC); |
| 646 | define('SORT_DIRECTION_DESC', DAO::SORT_DIRECTION_DESC); |
| 647 | } |
Below are the source code lines that represent each code path as identified by Xdebug. Please note a path is not
necessarily coterminous with a line, a line may contain multiple paths and therefore show up more than once.
Please also be aware that some paths may include implicit rather than explicit branches, e.g. an if statement
always has an else as part of its logical flow even if you didn't write one.
| 187 | $additionalValues = array_filter($arrFields, fn ($key) => !in_array($key, $keyCols), ARRAY_FILTER_USE_KEY); |
| 42 | public function __construct($callHooks = true) |
| 43 | { |
| 44 | if ($callHooks === true) { |
| 47 | $classNameParts = explode('\\', get_class($this)); // Separate namespace info from class name |
| 48 | if (Hook::run(strtolower(end($classNameParts)) . '::_Constructor', [$this])) { |
| 49 | return; |
| 42 | public function __construct($callHooks = true) |
| 43 | { |
| 44 | if ($callHooks === true) { |
| 47 | $classNameParts = explode('\\', get_class($this)); // Separate namespace info from class name |
| 48 | if (Hook::run(strtolower(end($classNameParts)) . '::_Constructor', [$this])) { |
| 52 | } |
| 42 | public function __construct($callHooks = true) |
| 43 | { |
| 44 | if ($callHooks === true) { |
| 52 | } |
| 206 | return $this->getInsertId(); |
| 207 | } |
| 142 | public function concat(...$args): string |
| 143 | { |
| 144 | return 'CONCAT(' . join(',', $args) . ')'; |
| 145 | } |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 275 | return null; |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 282 | case 'integer': |
| 284 | case 'float': |
| 285 | case 'number': |
| 287 | case 'object': |
| 288 | case 'array': |
| 290 | case 'date': |
| 292 | case 'string': |
| 292 | case 'string': |
| 295 | break; |
| 297 | return $value; |
| 298 | } |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 282 | case 'integer': |
| 284 | case 'float': |
| 285 | case 'number': |
| 287 | case 'object': |
| 288 | case 'array': |
| 290 | case 'date': |
| 292 | case 'string': |
| 295 | break; |
| 297 | return $value; |
| 298 | } |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 282 | case 'integer': |
| 284 | case 'float': |
| 285 | case 'number': |
| 287 | case 'object': |
| 288 | case 'array': |
| 290 | case 'date': |
| 291 | return strtotime($value); |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 282 | case 'integer': |
| 284 | case 'float': |
| 285 | case 'number': |
| 287 | case 'object': |
| 288 | case 'array': |
| 289 | return json_decode($value, true); |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 282 | case 'integer': |
| 284 | case 'float': |
| 285 | case 'number': |
| 287 | case 'object': |
| 289 | return json_decode($value, true); |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 282 | case 'integer': |
| 284 | case 'float': |
| 285 | case 'number': |
| 286 | return (float) $value; |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 282 | case 'integer': |
| 284 | case 'float': |
| 286 | return (float) $value; |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 282 | case 'integer': |
| 283 | return (int) $value; |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 283 | return (int) $value; |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 280 | return (bool) $value; |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 280 | return (bool) $value; |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 275 | return null; |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 282 | case 'integer': |
| 284 | case 'float': |
| 285 | case 'number': |
| 287 | case 'object': |
| 288 | case 'array': |
| 290 | case 'date': |
| 292 | case 'string': |
| 292 | case 'string': |
| 295 | break; |
| 297 | return $value; |
| 298 | } |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 282 | case 'integer': |
| 284 | case 'float': |
| 285 | case 'number': |
| 287 | case 'object': |
| 288 | case 'array': |
| 290 | case 'date': |
| 292 | case 'string': |
| 295 | break; |
| 297 | return $value; |
| 298 | } |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 282 | case 'integer': |
| 284 | case 'float': |
| 285 | case 'number': |
| 287 | case 'object': |
| 288 | case 'array': |
| 290 | case 'date': |
| 291 | return strtotime($value); |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 282 | case 'integer': |
| 284 | case 'float': |
| 285 | case 'number': |
| 287 | case 'object': |
| 288 | case 'array': |
| 289 | return json_decode($value, true); |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 282 | case 'integer': |
| 284 | case 'float': |
| 285 | case 'number': |
| 287 | case 'object': |
| 289 | return json_decode($value, true); |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 282 | case 'integer': |
| 284 | case 'float': |
| 285 | case 'number': |
| 286 | return (float) $value; |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 282 | case 'integer': |
| 284 | case 'float': |
| 286 | return (float) $value; |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 282 | case 'integer': |
| 283 | return (int) $value; |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 281 | case 'int': |
| 283 | return (int) $value; |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 279 | case 'boolean': |
| 280 | return (bool) $value; |
| 272 | public function convertFromDB(mixed $value, ?string $type, bool $nullable = false): mixed |
| 273 | { |
| 274 | if ($nullable && $value === null) { |
| 274 | if ($nullable && $value === null) { |
| 278 | case 'bool': |
| 280 | return (bool) $value; |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 331 | return null; |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 365 | case 'string': |
| 365 | case 'string': |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 365 | case 'string': |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 358 | if ($value !== null) { |
| 359 | if (!is_numeric($value)) { |
| 360 | $value = strtotime($value); |
| 361 | } |
| 362 | $value = date('Y-m-d H:i:s', $value); |
| 362 | $value = date('Y-m-d H:i:s', $value); |
| 363 | } |
| 364 | break; |
| 364 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 358 | if ($value !== null) { |
| 359 | if (!is_numeric($value)) { |
| 362 | $value = date('Y-m-d H:i:s', $value); |
| 363 | } |
| 364 | break; |
| 364 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 358 | if ($value !== null) { |
| 364 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 355 | $value = (float) $value; |
| 356 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 355 | $value = (float) $value; |
| 356 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 351 | $value = (int) $value; |
| 352 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 351 | $value = (int) $value; |
| 352 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 341 | $value = json_encode($value, JSON_UNESCAPED_UNICODE); |
| 342 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 341 | $value = json_encode($value, JSON_UNESCAPED_UNICODE); |
| 342 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 365 | case 'string': |
| 365 | case 'string': |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 365 | case 'string': |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 358 | if ($value !== null) { |
| 359 | if (!is_numeric($value)) { |
| 360 | $value = strtotime($value); |
| 361 | } |
| 362 | $value = date('Y-m-d H:i:s', $value); |
| 362 | $value = date('Y-m-d H:i:s', $value); |
| 363 | } |
| 364 | break; |
| 364 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 358 | if ($value !== null) { |
| 359 | if (!is_numeric($value)) { |
| 362 | $value = date('Y-m-d H:i:s', $value); |
| 363 | } |
| 364 | break; |
| 364 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 358 | if ($value !== null) { |
| 364 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 355 | $value = (float) $value; |
| 356 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 355 | $value = (float) $value; |
| 356 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 351 | $value = (int) $value; |
| 352 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 351 | $value = (int) $value; |
| 352 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 341 | $value = json_encode($value, JSON_UNESCAPED_UNICODE); |
| 342 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 341 | $value = json_encode($value, JSON_UNESCAPED_UNICODE); |
| 342 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 331 | return null; |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 365 | case 'string': |
| 365 | case 'string': |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 365 | case 'string': |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 358 | if ($value !== null) { |
| 359 | if (!is_numeric($value)) { |
| 360 | $value = strtotime($value); |
| 361 | } |
| 362 | $value = date('Y-m-d H:i:s', $value); |
| 362 | $value = date('Y-m-d H:i:s', $value); |
| 363 | } |
| 364 | break; |
| 364 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 358 | if ($value !== null) { |
| 359 | if (!is_numeric($value)) { |
| 362 | $value = date('Y-m-d H:i:s', $value); |
| 363 | } |
| 364 | break; |
| 364 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 358 | if ($value !== null) { |
| 364 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 355 | $value = (float) $value; |
| 356 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 355 | $value = (float) $value; |
| 356 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 351 | $value = (int) $value; |
| 352 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 351 | $value = (int) $value; |
| 352 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 340 | case 'array': |
| 341 | $value = json_encode($value, JSON_UNESCAPED_UNICODE); |
| 342 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 335 | $type = $this->getType($value); |
| 336 | } |
| 337 | |
| 338 | switch ($type) { |
| 339 | case 'object': |
| 339 | case 'object': |
| 341 | $value = json_encode($value, JSON_UNESCAPED_UNICODE); |
| 342 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 365 | case 'string': |
| 365 | case 'string': |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 365 | case 'string': |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 358 | if ($value !== null) { |
| 359 | if (!is_numeric($value)) { |
| 360 | $value = strtotime($value); |
| 361 | } |
| 362 | $value = date('Y-m-d H:i:s', $value); |
| 362 | $value = date('Y-m-d H:i:s', $value); |
| 363 | } |
| 364 | break; |
| 364 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 358 | if ($value !== null) { |
| 359 | if (!is_numeric($value)) { |
| 362 | $value = date('Y-m-d H:i:s', $value); |
| 363 | } |
| 364 | break; |
| 364 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 357 | case 'date': |
| 358 | if ($value !== null) { |
| 364 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 354 | case 'number': |
| 355 | $value = (float) $value; |
| 356 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 353 | case 'float': |
| 355 | $value = (float) $value; |
| 356 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 350 | case 'integer': |
| 351 | $value = (int) $value; |
| 352 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 349 | case 'int': |
| 351 | $value = (int) $value; |
| 352 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 344 | case 'boolean': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 343 | case 'bool': |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 347 | $value = ($value && $value !== 'false') ? 1 : 0; |
| 348 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 340 | case 'array': |
| 341 | $value = json_encode($value, JSON_UNESCAPED_UNICODE); |
| 342 | break; |
| 370 | return $value; |
| 371 | } |
| 328 | public function convertToDB(mixed $value, ?string &$type = null, bool $nullable = false) |
| 329 | { |
| 330 | if ($nullable && $value === null) { |
| 330 | if ($nullable && $value === null) { |
| 334 | if ($type === null) { |
| 339 | case 'object': |
| 341 | $value = json_encode($value, JSON_UNESCAPED_UNICODE); |
| 342 | break; |
| 370 | return $value; |
| 371 | } |
| 125 | public function countRecords(string|Builder $sql, array $params = []): int |
| 126 | { |
| 127 | // In case a Laravel Builder has been received, drop its SELECT and ORDER BY clauses for optimization purposes |
| 128 | if ($sql instanceof Builder) { |
| 129 | return $sql->getCountForPagination(); |
| 125 | public function countRecords(string|Builder $sql, array $params = []): int |
| 126 | { |
| 127 | // In case a Laravel Builder has been received, drop its SELECT and ORDER BY clauses for optimization purposes |
| 128 | if ($sql instanceof Builder) { |
| 131 | $result = $this->retrieve('SELECT COUNT(*) AS row_count FROM (' . $sql . ') AS count_subquery', $params); |
| 132 | return $result->current()->row_count; |
| 133 | } |
| 260 | public function dateFromDB(?string $d): ?string |
| 261 | { |
| 262 | return $d === null ? null : date('Y-m-d', strtotime($d)); |
| 262 | return $d === null ? null : date('Y-m-d', strtotime($d)); |
| 262 | return $d === null ? null : date('Y-m-d', strtotime($d)); |
| 263 | } |
| 260 | public function dateFromDB(?string $d): ?string |
| 261 | { |
| 262 | return $d === null ? null : date('Y-m-d', strtotime($d)); |
| 262 | return $d === null ? null : date('Y-m-d', strtotime($d)); |
| 262 | return $d === null ? null : date('Y-m-d', strtotime($d)); |
| 263 | } |
| 234 | public function dateToDB(null|int|string $d): string |
| 235 | { |
| 236 | if ($d === null) { |
| 237 | return 'NULL'; |
| 234 | public function dateToDB(null|int|string $d): string |
| 235 | { |
| 236 | if ($d === null) { |
| 239 | if (!ctype_digit($d)) { |
| 240 | $d = strtotime($d); |
| 241 | } |
| 242 | return '\'' . date('Y-m-d', $d) . '\''; |
| 242 | return '\'' . date('Y-m-d', $d) . '\''; |
| 243 | } |
| 234 | public function dateToDB(null|int|string $d): string |
| 235 | { |
| 236 | if ($d === null) { |
| 239 | if (!ctype_digit($d)) { |
| 242 | return '\'' . date('Y-m-d', $d) . '\''; |
| 243 | } |
| 250 | public function datetimeFromDB(?string $dt): ?string |
| 251 | { |
| 252 | return $dt === null ? null : date('Y-m-d H:i:s', strtotime($dt)); |
| 252 | return $dt === null ? null : date('Y-m-d H:i:s', strtotime($dt)); |
| 252 | return $dt === null ? null : date('Y-m-d H:i:s', strtotime($dt)); |
| 253 | } |
| 250 | public function datetimeFromDB(?string $dt): ?string |
| 251 | { |
| 252 | return $dt === null ? null : date('Y-m-d H:i:s', strtotime($dt)); |
| 252 | return $dt === null ? null : date('Y-m-d H:i:s', strtotime($dt)); |
| 252 | return $dt === null ? null : date('Y-m-d H:i:s', strtotime($dt)); |
| 253 | } |
| 216 | public function datetimeToDB(null|int|string $dt): string |
| 217 | { |
| 218 | if ($dt === null) { |
| 219 | return 'NULL'; |
| 216 | public function datetimeToDB(null|int|string $dt): string |
| 217 | { |
| 218 | if ($dt === null) { |
| 221 | if (!ctype_digit((string) $dt)) { |
| 222 | $dt = strtotime($dt); |
| 223 | } |
| 224 | return '\'' . date('Y-m-d H:i:s', $dt) . '\''; |
| 224 | return '\'' . date('Y-m-d H:i:s', $dt) . '\''; |
| 225 | } |
| 216 | public function datetimeToDB(null|int|string $dt): string |
| 217 | { |
| 218 | if ($dt === null) { |
| 221 | if (!ctype_digit((string) $dt)) { |
| 224 | return '\'' . date('Y-m-d H:i:s', $dt) . '\''; |
| 225 | } |
| 615 | protected function formatDateToDB(string $date, ?int $defaultNumWeeks = null, bool $acceptPastDate = true): ?string |
| 616 | { |
| 617 | $today = getDate(); |
| 618 | $todayTimestamp = mktime(0, 0, 0, $today['mon'], $today['mday'], $today['year']); |
| 619 | if ($date != null) { |
| 620 | $dateParts = explode('-', $date); |
| 621 | |
| 622 | // If we don't accept past dates... |
| 623 | if (!$acceptPastDate && $todayTimestamp > strtotime($date)) { |
| 623 | if (!$acceptPastDate && $todayTimestamp > strtotime($date)) { |
| 623 | if (!$acceptPastDate && $todayTimestamp > strtotime($date)) { |
| 625 | return date('Y-m-d H:i:s', $todayTimestamp); |
| 615 | protected function formatDateToDB(string $date, ?int $defaultNumWeeks = null, bool $acceptPastDate = true): ?string |
| 616 | { |
| 617 | $today = getDate(); |
| 618 | $todayTimestamp = mktime(0, 0, 0, $today['mon'], $today['mday'], $today['year']); |
| 619 | if ($date != null) { |
| 620 | $dateParts = explode('-', $date); |
| 621 | |
| 622 | // If we don't accept past dates... |
| 623 | if (!$acceptPastDate && $todayTimestamp > strtotime($date)) { |
| 623 | if (!$acceptPastDate && $todayTimestamp > strtotime($date)) { |
| 623 | if (!$acceptPastDate && $todayTimestamp > strtotime($date)) { |
| 628 | return date('Y-m-d H:i:s', mktime(0, 0, 0, $dateParts[1], $dateParts[2], $dateParts[0])); |
| 615 | protected function formatDateToDB(string $date, ?int $defaultNumWeeks = null, bool $acceptPastDate = true): ?string |
| 616 | { |
| 617 | $today = getDate(); |
| 618 | $todayTimestamp = mktime(0, 0, 0, $today['mon'], $today['mday'], $today['year']); |
| 619 | if ($date != null) { |
| 620 | $dateParts = explode('-', $date); |
| 621 | |
| 622 | // If we don't accept past dates... |
| 623 | if (!$acceptPastDate && $todayTimestamp > strtotime($date)) { |
| 623 | if (!$acceptPastDate && $todayTimestamp > strtotime($date)) { |
| 625 | return date('Y-m-d H:i:s', $todayTimestamp); |
| 615 | protected function formatDateToDB(string $date, ?int $defaultNumWeeks = null, bool $acceptPastDate = true): ?string |
| 616 | { |
| 617 | $today = getDate(); |
| 618 | $todayTimestamp = mktime(0, 0, 0, $today['mon'], $today['mday'], $today['year']); |
| 619 | if ($date != null) { |
| 620 | $dateParts = explode('-', $date); |
| 621 | |
| 622 | // If we don't accept past dates... |
| 623 | if (!$acceptPastDate && $todayTimestamp > strtotime($date)) { |
| 623 | if (!$acceptPastDate && $todayTimestamp > strtotime($date)) { |
| 628 | return date('Y-m-d H:i:s', mktime(0, 0, 0, $dateParts[1], $dateParts[2], $dateParts[0])); |
| 615 | protected function formatDateToDB(string $date, ?int $defaultNumWeeks = null, bool $acceptPastDate = true): ?string |
| 616 | { |
| 617 | $today = getDate(); |
| 618 | $todayTimestamp = mktime(0, 0, 0, $today['mon'], $today['mday'], $today['year']); |
| 619 | if ($date != null) { |
| 630 | } elseif (isset($defaultNumWeeks)) { |
| 632 | $numWeeks = max((int) $defaultNumWeeks, 2); |
| 633 | $newDueDateTimestamp = $todayTimestamp + ($numWeeks * 7 * 24 * 60 * 60); |
| 634 | return date('Y-m-d H:i:s', $newDueDateTimestamp); |
| 615 | protected function formatDateToDB(string $date, ?int $defaultNumWeeks = null, bool $acceptPastDate = true): ?string |
| 616 | { |
| 617 | $today = getDate(); |
| 618 | $todayTimestamp = mktime(0, 0, 0, $today['mon'], $today['mday'], $today['year']); |
| 619 | if ($date != null) { |
| 630 | } elseif (isset($defaultNumWeeks)) { |
| 637 | assert(false); |
| 638 | return null; |
| 639 | } |
| 640 | } |
| 394 | $returner = []; |
| 395 | // Call hooks based on the calling entity, assuming |
| 396 | // this method is only called by a subclass. Results |
| 397 | // in hook calls named e.g. "DAO_CLASS::getAdditionalFieldNames" |
| 398 | // (class names lowercase) |
| 399 | $classNameParts = explode('\\', get_class($this)); // Separate namespace info from class name |
| 400 | Hook::run(strtolower(end($classNameParts)) . '::getAdditionalFieldNames', [$this, &$returner]); |
| 401 | |
| 402 | return $returner; |
| 403 | } |
| 584 | public static function getDataChangedEvent(?string $elementId = null, ?string $parentElementId = null, string $content = ''): JSONMessage |
| 585 | { |
| 586 | // Create the event data. |
| 587 | $eventData = null; |
| 588 | if ($elementId) { |
| 589 | $eventData = [$elementId]; |
| 590 | if (strlen($parentElementId ?? '') > 0) { |
| 591 | $eventData['parentElementId'] = $parentElementId; |
| 592 | } |
| 593 | } |
| 594 | |
| 595 | // Create and render the JSON message with the |
| 596 | // event to be triggered on the client side. |
| 597 | $json = new JSONMessage(true, $content); |
| 597 | $json = new JSONMessage(true, $content); |
| 598 | $json->setEvent('dataChanged', $eventData); |
| 599 | return $json; |
| 600 | } |
| 584 | public static function getDataChangedEvent(?string $elementId = null, ?string $parentElementId = null, string $content = ''): JSONMessage |
| 585 | { |
| 586 | // Create the event data. |
| 587 | $eventData = null; |
| 588 | if ($elementId) { |
| 589 | $eventData = [$elementId]; |
| 590 | if (strlen($parentElementId ?? '') > 0) { |
| 597 | $json = new JSONMessage(true, $content); |
| 598 | $json->setEvent('dataChanged', $eventData); |
| 599 | return $json; |
| 600 | } |
| 584 | public static function getDataChangedEvent(?string $elementId = null, ?string $parentElementId = null, string $content = ''): JSONMessage |
| 585 | { |
| 586 | // Create the event data. |
| 587 | $eventData = null; |
| 588 | if ($elementId) { |
| 597 | $json = new JSONMessage(true, $content); |
| 598 | $json->setEvent('dataChanged', $eventData); |
| 599 | return $json; |
| 600 | } |
| 532 | public function getDataObjectSettings(string $tableName, string $idFieldName, int $idFieldValue, DataObject $dataObject) |
| 533 | { |
| 534 | if ($idFieldName !== null) { |
| 534 | if ($idFieldName !== null) { |
| 535 | $sql = "SELECT * FROM {$tableName} WHERE {$idFieldName} = ?"; |
| 541 | $result = $this->retrieve($sql, $params); |
| 542 | foreach ($result as $row) { |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 549 | empty($row->locale) ? null : $row->locale |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 542 | foreach ($result as $row) { |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 550 | ); |
| 551 | } |
| 552 | } |
| 532 | public function getDataObjectSettings(string $tableName, string $idFieldName, int $idFieldValue, DataObject $dataObject) |
| 533 | { |
| 534 | if ($idFieldName !== null) { |
| 534 | if ($idFieldName !== null) { |
| 535 | $sql = "SELECT * FROM {$tableName} WHERE {$idFieldName} = ?"; |
| 541 | $result = $this->retrieve($sql, $params); |
| 542 | foreach ($result as $row) { |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 549 | empty($row->locale) ? null : $row->locale |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 542 | foreach ($result as $row) { |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 550 | ); |
| 551 | } |
| 552 | } |
| 532 | public function getDataObjectSettings(string $tableName, string $idFieldName, int $idFieldValue, DataObject $dataObject) |
| 533 | { |
| 534 | if ($idFieldName !== null) { |
| 534 | if ($idFieldName !== null) { |
| 535 | $sql = "SELECT * FROM {$tableName} WHERE {$idFieldName} = ?"; |
| 541 | $result = $this->retrieve($sql, $params); |
| 542 | foreach ($result as $row) { |
| 542 | foreach ($result as $row) { |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 550 | ); |
| 551 | } |
| 552 | } |
| 532 | public function getDataObjectSettings(string $tableName, string $idFieldName, int $idFieldValue, DataObject $dataObject) |
| 533 | { |
| 534 | if ($idFieldName !== null) { |
| 534 | if ($idFieldName !== null) { |
| 535 | $sql = "SELECT * FROM {$tableName} WHERE {$idFieldName} = ?"; |
| 541 | $result = $this->retrieve($sql, $params); |
| 542 | foreach ($result as $row) { |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 550 | ); |
| 551 | } |
| 552 | } |
| 532 | public function getDataObjectSettings(string $tableName, string $idFieldName, int $idFieldValue, DataObject $dataObject) |
| 533 | { |
| 534 | if ($idFieldName !== null) { |
| 538 | $sql = "SELECT * FROM {$tableName}"; |
| 539 | $params = []; |
| 540 | } |
| 541 | $result = $this->retrieve($sql, $params); |
| 541 | $result = $this->retrieve($sql, $params); |
| 542 | foreach ($result as $row) { |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 549 | empty($row->locale) ? null : $row->locale |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 542 | foreach ($result as $row) { |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 550 | ); |
| 551 | } |
| 552 | } |
| 532 | public function getDataObjectSettings(string $tableName, string $idFieldName, int $idFieldValue, DataObject $dataObject) |
| 533 | { |
| 534 | if ($idFieldName !== null) { |
| 538 | $sql = "SELECT * FROM {$tableName}"; |
| 539 | $params = []; |
| 540 | } |
| 541 | $result = $this->retrieve($sql, $params); |
| 541 | $result = $this->retrieve($sql, $params); |
| 542 | foreach ($result as $row) { |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 549 | empty($row->locale) ? null : $row->locale |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 542 | foreach ($result as $row) { |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 550 | ); |
| 551 | } |
| 552 | } |
| 532 | public function getDataObjectSettings(string $tableName, string $idFieldName, int $idFieldValue, DataObject $dataObject) |
| 533 | { |
| 534 | if ($idFieldName !== null) { |
| 538 | $sql = "SELECT * FROM {$tableName}"; |
| 539 | $params = []; |
| 540 | } |
| 541 | $result = $this->retrieve($sql, $params); |
| 541 | $result = $this->retrieve($sql, $params); |
| 542 | foreach ($result as $row) { |
| 542 | foreach ($result as $row) { |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 550 | ); |
| 551 | } |
| 552 | } |
| 532 | public function getDataObjectSettings(string $tableName, string $idFieldName, int $idFieldValue, DataObject $dataObject) |
| 533 | { |
| 534 | if ($idFieldName !== null) { |
| 538 | $sql = "SELECT * FROM {$tableName}"; |
| 539 | $params = []; |
| 540 | } |
| 541 | $result = $this->retrieve($sql, $params); |
| 541 | $result = $this->retrieve($sql, $params); |
| 542 | foreach ($result as $row) { |
| 542 | foreach ($result as $row) { |
| 543 | $dataObject->setData( |
| 544 | $row->setting_name, |
| 545 | $this->convertFromDB( |
| 546 | $row->setting_value, |
| 547 | $row->setting_type |
| 548 | ), |
| 549 | empty($row->locale) ? null : $row->locale |
| 550 | ); |
| 551 | } |
| 552 | } |
| 559 | public function getDirectionMapping(int $direction): string |
| 560 | { |
| 561 | return match($direction) { |
| 562 | self::SORT_DIRECTION_ASC => 'ASC', |
| 564 | default => 'ASC' |
| 565 | }; |
| 566 | } |
| 559 | public function getDirectionMapping(int $direction): string |
| 560 | { |
| 561 | return match($direction) { |
| 563 | self::SORT_DIRECTION_DESC => 'DESC', |
| 564 | default => 'ASC' |
| 565 | }; |
| 566 | } |
| 559 | public function getDirectionMapping(int $direction): string |
| 560 | { |
| 561 | return match($direction) { |
| 564 | default => 'ASC' |
| 564 | default => 'ASC' |
| 565 | }; |
| 566 | } |
| 196 | return DB::getPdo()->lastInsertId(); |
| 197 | } |
| 416 | $returner = []; |
| 417 | // Call hooks based on the calling entity, assuming |
| 418 | // this method is only called by a subclass. Results |
| 419 | // in hook calls named e.g. "DAO_CLASS::getLocaleFieldNames" |
| 420 | // (class names lowercase) |
| 421 | $classNameParts = explode('\\', get_class($this)); // Separate namespace info from class name |
| 422 | Hook::run(strtolower(end($classNameParts)) . '::getLocaleFieldNames', [$this, &$returner]); |
| 423 | |
| 424 | return $returner; |
| 425 | } |
| 305 | public function getType(mixed $value): string |
| 306 | { |
| 307 | return match(gettype($value)) { |
| 308 | 'boolean' => 'bool', |
| 317 | default => 'string' |
| 318 | }; |
| 319 | } |
| 305 | public function getType(mixed $value): string |
| 306 | { |
| 307 | return match(gettype($value)) { |
| 309 | 'bool' => 'bool', |
| 317 | default => 'string' |
| 318 | }; |
| 319 | } |
| 305 | public function getType(mixed $value): string |
| 306 | { |
| 307 | return match(gettype($value)) { |
| 310 | 'integer' => 'int', |
| 317 | default => 'string' |
| 318 | }; |
| 319 | } |
| 305 | public function getType(mixed $value): string |
| 306 | { |
| 307 | return match(gettype($value)) { |
| 311 | 'int' => 'int', |
| 317 | default => 'string' |
| 318 | }; |
| 319 | } |
| 305 | public function getType(mixed $value): string |
| 306 | { |
| 307 | return match(gettype($value)) { |
| 312 | 'double' => 'float', |
| 317 | default => 'string' |
| 318 | }; |
| 319 | } |
| 305 | public function getType(mixed $value): string |
| 306 | { |
| 307 | return match(gettype($value)) { |
| 313 | 'float' => 'float', |
| 317 | default => 'string' |
| 318 | }; |
| 319 | } |
| 305 | public function getType(mixed $value): string |
| 306 | { |
| 307 | return match(gettype($value)) { |
| 314 | 'array' => 'object', |
| 317 | default => 'string' |
| 318 | }; |
| 319 | } |
| 305 | public function getType(mixed $value): string |
| 306 | { |
| 307 | return match(gettype($value)) { |
| 315 | 'object' => 'object', |
| 317 | default => 'string' |
| 318 | }; |
| 319 | } |
| 305 | public function getType(mixed $value): string |
| 306 | { |
| 307 | return match(gettype($value)) { |
| 316 | 'string' => 'string', |
| 317 | default => 'string' |
| 318 | }; |
| 319 | } |
| 305 | public function getType(mixed $value): string |
| 306 | { |
| 307 | return match(gettype($value)) { |
| 317 | default => 'string' |
| 317 | default => 'string' |
| 318 | }; |
| 319 | } |
| 378 | public function nullOrInt(mixed $value): ?int |
| 379 | { |
| 380 | return (empty($value) ? null : (int) $value); |
| 380 | return (empty($value) ? null : (int) $value); |
| 380 | return (empty($value) ? null : (int) $value); |
| 381 | } |
| 378 | public function nullOrInt(mixed $value): ?int |
| 379 | { |
| 380 | return (empty($value) ? null : (int) $value); |
| 380 | return (empty($value) ? null : (int) $value); |
| 380 | return (empty($value) ? null : (int) $value); |
| 381 | } |
| 184 | public function replace(string $table, array $arrFields, array $keyCols): void |
| 185 | { |
| 186 | $matchValues = array_filter($arrFields, fn ($key) => in_array($key, $keyCols), ARRAY_FILTER_USE_KEY); |
| 187 | $additionalValues = array_filter($arrFields, fn ($key) => !in_array($key, $keyCols), ARRAY_FILTER_USE_KEY); |
| 188 | DB::table($table)->updateOrInsert($matchValues, $additionalValues); |
| 189 | } |
| 64 | public function retrieve(string $sql, array $params = [], bool $callHooks = true): Generator |
| 65 | { |
| 66 | if ($callHooks === true) { |
| 67 | $trace = debug_backtrace(); |
| 68 | // Call hooks based on the calling entity, assuming |
| 69 | // this method is only called by a subclass. Results |
| 70 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 71 | // (always lower case). |
| 72 | $value = null; |
| 73 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$value])) { |
| 74 | return $value; |
| 64 | public function retrieve(string $sql, array $params = [], bool $callHooks = true): Generator |
| 65 | { |
| 66 | if ($callHooks === true) { |
| 67 | $trace = debug_backtrace(); |
| 68 | // Call hooks based on the calling entity, assuming |
| 69 | // this method is only called by a subclass. Results |
| 70 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 71 | // (always lower case). |
| 72 | $value = null; |
| 73 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$value])) { |
| 78 | return DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 79 | } |
| 64 | public function retrieve(string $sql, array $params = [], bool $callHooks = true): Generator |
| 65 | { |
| 66 | if ($callHooks === true) { |
| 78 | return DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 79 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 93 | $trace = debug_backtrace(); |
| 94 | // Call hooks based on the calling entity, assuming |
| 95 | // this method is only called by a subclass. Results |
| 96 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 97 | $value = null; |
| 98 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$dbResultRange, &$value])) { |
| 99 | return $value; |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 93 | $trace = debug_backtrace(); |
| 94 | // Call hooks based on the calling entity, assuming |
| 95 | // this method is only called by a subclass. Results |
| 96 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 97 | $value = null; |
| 98 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$dbResultRange, &$value])) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 107 | if ($sql instanceof Builder) { |
| 108 | $sql->limit($limit)->offset($offset); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 93 | $trace = debug_backtrace(); |
| 94 | // Call hooks based on the calling entity, assuming |
| 95 | // this method is only called by a subclass. Results |
| 96 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 97 | $value = null; |
| 98 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$dbResultRange, &$value])) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 107 | if ($sql instanceof Builder) { |
| 108 | $sql->limit($limit)->offset($offset); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 93 | $trace = debug_backtrace(); |
| 94 | // Call hooks based on the calling entity, assuming |
| 95 | // this method is only called by a subclass. Results |
| 96 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 97 | $value = null; |
| 98 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$dbResultRange, &$value])) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 110 | $sql .= " LIMIT {$limit} OFFSET {$offset}"; |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 93 | $trace = debug_backtrace(); |
| 94 | // Call hooks based on the calling entity, assuming |
| 95 | // this method is only called by a subclass. Results |
| 96 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 97 | $value = null; |
| 98 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$dbResultRange, &$value])) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 110 | $sql .= " LIMIT {$limit} OFFSET {$offset}"; |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 93 | $trace = debug_backtrace(); |
| 94 | // Call hooks based on the calling entity, assuming |
| 95 | // this method is only called by a subclass. Results |
| 96 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 97 | $value = null; |
| 98 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$dbResultRange, &$value])) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 93 | $trace = debug_backtrace(); |
| 94 | // Call hooks based on the calling entity, assuming |
| 95 | // this method is only called by a subclass. Results |
| 96 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 97 | $value = null; |
| 98 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$dbResultRange, &$value])) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 93 | $trace = debug_backtrace(); |
| 94 | // Call hooks based on the calling entity, assuming |
| 95 | // this method is only called by a subclass. Results |
| 96 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 97 | $value = null; |
| 98 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$dbResultRange, &$value])) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 107 | if ($sql instanceof Builder) { |
| 108 | $sql->limit($limit)->offset($offset); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 93 | $trace = debug_backtrace(); |
| 94 | // Call hooks based on the calling entity, assuming |
| 95 | // this method is only called by a subclass. Results |
| 96 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 97 | $value = null; |
| 98 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$dbResultRange, &$value])) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 107 | if ($sql instanceof Builder) { |
| 108 | $sql->limit($limit)->offset($offset); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 93 | $trace = debug_backtrace(); |
| 94 | // Call hooks based on the calling entity, assuming |
| 95 | // this method is only called by a subclass. Results |
| 96 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 97 | $value = null; |
| 98 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$dbResultRange, &$value])) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 110 | $sql .= " LIMIT {$limit} OFFSET {$offset}"; |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 93 | $trace = debug_backtrace(); |
| 94 | // Call hooks based on the calling entity, assuming |
| 95 | // this method is only called by a subclass. Results |
| 96 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 97 | $value = null; |
| 98 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$dbResultRange, &$value])) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 110 | $sql .= " LIMIT {$limit} OFFSET {$offset}"; |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 93 | $trace = debug_backtrace(); |
| 94 | // Call hooks based on the calling entity, assuming |
| 95 | // this method is only called by a subclass. Results |
| 96 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 97 | $value = null; |
| 98 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$dbResultRange, &$value])) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 93 | $trace = debug_backtrace(); |
| 94 | // Call hooks based on the calling entity, assuming |
| 95 | // this method is only called by a subclass. Results |
| 96 | // in hook calls named e.g. "DAO_CLASS::_get..." |
| 97 | $value = null; |
| 98 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$dbResultRange, &$value])) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 107 | if ($sql instanceof Builder) { |
| 108 | $sql->limit($limit)->offset($offset); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 107 | if ($sql instanceof Builder) { |
| 108 | $sql->limit($limit)->offset($offset); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 110 | $sql .= " LIMIT {$limit} OFFSET {$offset}"; |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 110 | $sql .= " LIMIT {$limit} OFFSET {$offset}"; |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 107 | if ($sql instanceof Builder) { |
| 108 | $sql->limit($limit)->offset($offset); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 107 | if ($sql instanceof Builder) { |
| 108 | $sql->limit($limit)->offset($offset); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 110 | $sql .= " LIMIT {$limit} OFFSET {$offset}"; |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 104 | $limit = (int) $dbResultRange->getCount(); |
| 105 | $offset = (int) $dbResultRange->getOffset(); |
| 106 | $offset += max(0, $dbResultRange->getPage() - 1) * (int) $dbResultRange->getCount(); |
| 107 | if ($sql instanceof Builder) { |
| 110 | $sql .= " LIMIT {$limit} OFFSET {$offset}"; |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 90 | public function retrieveRange(string|Builder $sql, array $params = [], ?DBResultRange $dbResultRange = null, bool $callHooks = true): Iterable |
| 91 | { |
| 92 | if ($callHooks === true) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 103 | if ($dbResultRange && $dbResultRange->isValid()) { |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 114 | return $sql instanceof Builder ? $sql->get() : DB::cursor(DB::raw($sql)->getValue(DB::connection()->getQueryGrammar()), $params); |
| 115 | } |
| 159 | public function update(string $sql, array $params = [], bool $callHooks = true, bool $dieOnError = true): int |
| 160 | { |
| 161 | if ($callHooks === true) { |
| 162 | $trace = debug_backtrace(); |
| 163 | // Call hooks based on the calling entity, assuming |
| 164 | // this method is only called by a subclass. Results |
| 165 | // in hook calls named e.g. "DAO_CLASS::_updateobject" |
| 166 | // (all lowercase) |
| 167 | $value = null; |
| 168 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$value])) { |
| 169 | return $value; |
| 159 | public function update(string $sql, array $params = [], bool $callHooks = true, bool $dieOnError = true): int |
| 160 | { |
| 161 | if ($callHooks === true) { |
| 162 | $trace = debug_backtrace(); |
| 163 | // Call hooks based on the calling entity, assuming |
| 164 | // this method is only called by a subclass. Results |
| 165 | // in hook calls named e.g. "DAO_CLASS::_updateobject" |
| 166 | // (all lowercase) |
| 167 | $value = null; |
| 168 | if (Hook::run(strtolower($trace[1]['class'] . '::_' . $trace[1]['function']), [&$sql, &$params, &$value])) { |
| 173 | return DB::affectingStatement($sql, $params); |
| 174 | } |
| 159 | public function update(string $sql, array $params = [], bool $callHooks = true, bool $dieOnError = true): int |
| 160 | { |
| 161 | if ($callHooks === true) { |
| 173 | return DB::affectingStatement($sql, $params); |
| 174 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 474 | assert(false); |
| 475 | continue; |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 474 | assert(false); |
| 475 | continue; |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 474 | assert(false); |
| 475 | continue; |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 474 | assert(false); |
| 475 | continue; |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 474 | assert(false); |
| 475 | continue; |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 468 | if ($isTranslated) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 486 | foreach ($values as $locale => $value) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 506 | $removeWhere = ''; |
| 507 | $removeParams = []; |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 508 | foreach ($idArray as $idField => $idValue) { |
| 509 | if (!empty($removeWhere)) { |
| 510 | $removeWhere .= ' AND '; |
| 511 | } |
| 512 | $removeWhere .= $idField . ' = ?'; |
| 513 | $removeParams[] = $idValue; |
| 514 | } |
| 515 | $removeWhere .= rtrim(' AND setting_name IN ( ' . str_repeat('? ,', count($staleSettings)), ',') . ')'; |
| 516 | $removeParams = array_merge($removeParams, $staleSettings); |
| 517 | $removeSql = 'DELETE FROM ' . $tableName . ' WHERE ' . $removeWhere; |
| 518 | $this->update($removeSql, $removeParams); |
| 519 | } |
| 520 | } |
| 520 | } |
| 432 | public function updateDataObjectSettings(string $tableName, DataObject $dataObject, array $idArray) |
| 433 | { |
| 434 | // Initialize variables |
| 435 | $idFields = array_keys($idArray); |
| 436 | $idFields[] = 'locale'; |
| 437 | $idFields[] = 'setting_name'; |
| 438 | |
| 439 | // Build a data structure that we can process efficiently. |
| 440 | $translated = $metadata = 1; |
| 441 | $settings = !$metadata; |
| 442 | $settingFields = [ |
| 443 | // Translated data |
| 444 | $translated => [ |
| 445 | $settings => $this->getLocaleFieldNames(), |
| 446 | $metadata => $dataObject->getLocaleMetadataFieldNames() |
| 447 | ], |
| 448 | // Shared data |
| 449 | !$translated => [ |
| 450 | $settings => $this->getAdditionalFieldNames(), |
| 451 | $metadata => $dataObject->getAdditionalMetadataFieldNames() |
| 452 | ] |
| 453 | ]; |
| 454 | |
| 455 | // Loop over all fields and update them in the settings table |
| 456 | $updateArray = $idArray; |
| 457 | $noLocale = 0; |
| 458 | $staleSettings = []; |
| 459 | |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 460 | foreach ($settingFields as $isTranslated => $fieldTypes) { |
| 461 | foreach ($fieldTypes as $isMetadata => $fieldNames) { |
| 462 | foreach ($fieldNames as $fieldName) { |
| 463 | // Now we have the following control data: |
| 464 | // - $isTranslated: true for translated data, false data shared between locales |
| 465 | // - $isMetadata: true for metadata fields, false for normal settings |
| 466 | // - $fieldName: the field in the data object to be updated |
| 467 | if ($dataObject->hasData($fieldName)) { |
| 468 | if ($isTranslated) { |
| 469 | // Translated data comes in as an array |
| 470 | // with the locale as the key. |
| 471 | $values = $dataObject->getData($fieldName) ?? []; |
| 472 | if (!is_array($values)) { |
| 473 | // Inconsistent data: should have been an array |
| 474 | assert(false); |
| 475 | continue; |
| 476 | } |
| 477 | } else { |
| 478 | // Transform shared data into an array so that |
| 479 | // we can handle them the same way as translated data. |
| 480 | $values = [ |
| 481 | $noLocale => $dataObject->getData($fieldName) |
| 482 | ]; |
| 483 | } |
| 484 | |
| 485 | // Loop over the values and update them in the database |
| 486 | foreach ($values as $locale => $value) { |
| 487 | $updateArray['locale'] = ($locale === $noLocale ? '' : $locale); |
| 488 | $updateArray['setting_name'] = $fieldName; |
| 489 | $updateArray['setting_type'] = null; |
| 490 | // Convert the data value and implicitly set the setting type. |
| 491 | $updateArray['setting_value'] = $this->convertToDB($value, $updateArray['setting_type']); |
| 492 | $this->replace($tableName, $updateArray, $idFields); |
| 493 | } |
| 494 | } else { |
| 495 | // Data is maintained "sparsely". Only set fields will be |
| 496 | // recorded in the settings table. Fields that are not explicity set |
| 497 | // in the data object will be deleted. |
| 498 | $staleSettings[] = $fieldName; |
| 499 | } |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | // Remove stale data |
| 505 | if (count($staleSettings)) { |
| 520 | } |